/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dmcn.bl.genetics.fitnessfunction;

import dmcn.bl.genetics.input.Input;
import java.util.Random;
import org.jgap.Gene;
import org.jgap.IChromosome;

/**
 *
 * @author Spyros
 */
public class Evaluator {

    private int numOfConcetrators;
    private int numOfTerminals;
    private Input input;

    public Evaluator(Input input) {
        this.numOfConcetrators = input.getSygkentrotes();
        this.numOfTerminals = input.getPhges();
        this.input = input;
    }

    protected Double evaluate(IChromosome ic) {

        Integer[][] cost = input.getKostos();//calculateCost(numOfConcetrators, numOfTerminals);
        Integer[] fortio = input.getFortio();//calculatefortio(numOfTerminals);
        Integer[] xwritikothta = input.getXwritikothta();//calculateXwritikotita(numOfConcetrators);
        Double fitness = 0D;
        Gene[] genes = ic.getGenes();
        if (restriction1(numOfConcetrators, numOfTerminals, ic.getGenes())
                && restriction2(numOfConcetrators, numOfTerminals, ic.getGenes(), fortio, xwritikothta)) {

            for (int i = 0; i < numOfConcetrators; i++) {
                for (int j = 0; j < numOfTerminals; j++) {
                    fitness = fitness + (cost[i][j] * ((Integer) genes[i * numOfTerminals + j].getAllele()));
                }
            }
//            System.out.println(fitness);
        } else {
            fitness = null;
        }
        return fitness;




    }

    /**
     * phgh se ena akrivws sugkentroth
     */
    public boolean restriction1(int numOfConcetrators, int numOfTerminals, Gene[] solution) {
        int sum;

        //ta terminal kai concetrators prepei na einai anapoda
        for (int j = 0; j < numOfTerminals; j++) {
            sum = 0;
            for (int i = 0; i < numOfConcetrators; i++) {
                sum = sum + ((Integer) solution[i * numOfTerminals + j].getAllele()).intValue();
            }
            if (sum > 1 || sum == 0) {
                return false;
            }
        }
        return true;
    }

    /**
     * xwritikothta kai fortio
     */
    public boolean restriction2(int numOfConcetrators, int numOfTerminals, Gene[] solution, Integer[] fortio, Integer[] xwritikothta) {
        int sunolikoFortio;
        for (int i = 0; i < numOfConcetrators; i++) {
            sunolikoFortio = 0;
            for (int j = 0; j < numOfTerminals; j++) {
                sunolikoFortio = sunolikoFortio + ((Integer) solution[i * numOfTerminals + j].getAllele() * fortio[i]);
            }
            if (sunolikoFortio > xwritikothta[i].intValue()) {
                return false;
            }
        }
        return true;
    }

    private Integer[][] calculateCost(int numOfConcetrators, int numOfTerminals) {
        Random rand = new Random();
        Integer[][] costResult = new Integer[numOfTerminals][numOfConcetrators];
        for (int i = 0; i < numOfTerminals; i++) {
            for (int j = 0; j < numOfConcetrators; j++) {
                costResult[i][j] = rand.nextInt(1000);
            }
        }
        return costResult;
    }

    private Integer[] calculatefortio(int numOfTerminals) {
        Random rand = new Random();
        Integer[] fortioResult = new Integer[numOfTerminals];

        for (int j = 0; j < numOfTerminals; j++) {
            fortioResult[j] = rand.nextInt(300);
        }

        return fortioResult;
    }

    private Integer[] calculateXwritikotita(int numOfConcetrators) {
        Random rand = new Random();
        Integer[] xwritikotitaResult = new Integer[numOfConcetrators];
        for (int i = 0; i < numOfConcetrators; i++) {

            xwritikotitaResult[i] = rand.nextInt(5000);

        }
        return xwritikotitaResult;
    }
}
